package com.am.server.api.system.user.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.am.server.api.system.log.aspect.annotation.WriteLog;
import com.am.server.api.system.user.constant.UserLogConstant;
import com.am.server.api.system.user.constant.UserMessageConstant;
import com.am.server.api.system.user.constant.UserPermissionConstant;
import com.am.server.api.system.user.model.dto.*;
import com.am.server.api.system.user.service.AdminUserService;
import com.am.server.common.base.model.dto.PageDto;
import com.am.server.common.base.model.dto.ResponseMessageDto;
import com.am.server.common.constant.Constant;
import com.am.server.common.constant.MessageConstant;
import com.am.server.common.util.ResponseUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 用户管理
 *
 * @author 阮雪峰
 */
@SaCheckLogin
@WriteLog(UserLogConstant.MENU_NAME)
@RestController
@RequestMapping(Constant.ADMIN_ROOT + "/user")
public class AdminUserController {

    private final AdminUserService adminUserService;

    public AdminUserController(AdminUserService adminUserService) {
        this.adminUserService = adminUserService;
    }

    /**
     * 列表查询
     *
     * @param query query
     * @return org.springframework.http.ResponseEntity
     * @author 阮雪峰
     */
    @GetMapping("/find")
    public ResponseEntity<PageDto<AdminUserDto>> find(AdminUserListQueryDto query) {
        return ResponseUtils.ok(adminUserService.find(query));
    }

    /**
     * 新增
     *
     * @param dto 用户信息
     * @return org.springframework.http.ResponseEntity
     */
    @SaCheckPermission(UserPermissionConstant.PERMISSION_USER_ADD)
    @WriteLog(UserLogConstant.USER_ADD_METHOD_NAME)
    @PostMapping("/save")
    public ResponseEntity<ResponseMessageDto> save(@Validated @RequestBody SaveAdminUserDto dto) {
        //检验邮箱是否存在
        if (Boolean.TRUE.equals(adminUserService.isEmailExist(dto.getEmail()))) {
            return ResponseUtils.badRequest(UserMessageConstant.EMAIL_EXIST);
        }

        if (Boolean.TRUE.equals(adminUserService.isUsernameExist(dto.getUsername()))) {
            return ResponseUtils.badRequest(UserMessageConstant.USERNAME_EXIST);
        }

        adminUserService.save(dto);

        return ResponseUtils.ok(MessageConstant.SAVE_SUCCESS);
    }

    /**
     * 修改
     *
     * @param dto 用户信息
     * @return org.springframework.http.ResponseEntity
     */
    @SaCheckPermission(UserPermissionConstant.PERMISSION_USER_UPDATE)
    @WriteLog(UserLogConstant.USER_UPDATE_METHOD_NAME)
    @PostMapping("/update")
    public ResponseEntity<ResponseMessageDto> update(@RequestBody @Validated UpdateAdminUserDto dto) {
        if (Boolean.TRUE.equals(adminUserService.isEmailExistWithId(dto.getEmail(), dto.getId()))) {
            return ResponseUtils.badRequest(UserMessageConstant.USERNAME_EXIST);
        }

        if (Boolean.TRUE.equals(adminUserService.isUsernameExistWithId(dto.getUsername(), dto.getId()))) {
            return ResponseUtils.badRequest(UserMessageConstant.USERNAME_EXIST);
        }

        adminUserService.update(dto);

        return ResponseUtils.ok(MessageConstant.SUCCESS);
    }

    /**
     * 删除
     *
     * @param id 用户主键
     * @return org.springframework.http.ResponseEntity
     */
    @SaCheckPermission(UserPermissionConstant.PERMISSION_USER_DELETE)
    @WriteLog(UserLogConstant.USER_DELETE_METHOD_NAME)
    @DeleteMapping("/delete")
    public ResponseEntity<ResponseMessageDto> delete(Long id) {
        if (id == null) {
            return ResponseUtils.badRequest(MessageConstant.COMMON_DELETE_PRIMARY_KEY_NULL);
        }
        if (id.equals(StpUtil.getLoginIdAsLong())) {
            return ResponseUtils.badRequest(UserMessageConstant.NOT_ALLOW_DELETE_YOURSELF);
        }

        adminUserService.delete(id);

        return ResponseUtils.ok(MessageConstant.DELETE_SUCCESS);
    }

    /**
     * 重置密码
     *
     * @param id 用户主键
     * @return org.springframework.http.ResponseEntity
     */
    @SaCheckPermission(UserPermissionConstant.PERMISSION_USER_RESET_PASSWORD)
    @WriteLog("重置密码")
    @PutMapping("/reset/password")
    public ResponseEntity<ResponseMessageDto> resetPassword(Long id) {
        if (Objects.isNull(id)) {
            return ResponseUtils.badRequest(MessageConstant.COMMON_OPERATE_PRIMARY_KEY_NULL);
        }
        adminUserService.resetPassword(id);
        return ResponseUtils.ok(UserMessageConstant.PASSWORD_RESET_SUCCESS);
    }

    /**
     * 修改角色
     *
     * @param dto 用户信息
     */
    @SaCheckPermission(UserPermissionConstant.PERMISSION_USER_CHANGE_ROLE)
    @WriteLog(UserLogConstant.USER_CHANGE_ROLE_METHOD_NAME)
    @PostMapping("/update/role")
    public ResponseEntity<ResponseMessageDto> updateRole(@Validated @RequestBody UpdateRoleDto dto) {
        adminUserService.updateRole(dto);
        return ResponseUtils.ok(MessageConstant.UPDATE_SUCCESS);
    }

    /**
     * 邮箱是否被使用
     *
     * @param dto 用户信息
     * @return org.springframework.http.ResponseEntity
     */
    @GetMapping("/isEmailExist")
    public ResponseEntity<Boolean> isEmailExist(EmailExistQueryDto dto) {
        return ResponseUtils.ok(
                Optional.of(dto)
                        .map(EmailExistQueryDto::getId)
                        .map(id -> adminUserService.isEmailExistWithId(dto.getEmail(), id))
                        .orElseGet(() -> adminUserService.isEmailExist(dto.getEmail()))
        );
    }

    /**
     * 用户名是否被使用
     *
     * @param dto dto
     * @return org.springframework.http.ResponseEntity
     */
    @GetMapping("/isUsernameExist")
    public ResponseEntity<Boolean> isUsernameExist(UsernameExistDto dto) {
        return ResponseUtils.ok(
                Optional.of(dto)
                        .map(UsernameExistDto::getId)
                        .map(id -> adminUserService.isUsernameExistWithId(dto.getUsername(), id))
                        .orElseGet(() -> adminUserService.isUsernameExist(dto.getUsername()))
        );
    }

    /**
     * 查询用户拥有角色的id
     *
     * @param id id
     * @return org.springframework.http.ResponseEntity
     */
    @GetMapping("roleIdList")
    public ResponseEntity<List<Long>> roleIdList(Long id) {
        return ResponseUtils.ok(adminUserService.findRoleIdList(id));
    }
}
